home *** CD-ROM | disk | FTP | other *** search
/ Chip 2007 January, February, March & April / Chip-Cover-CD-2007-02.iso / Pakiet bezpieczenstwa / mini Pentoo LiveCD 2006.1 / mpentoo-2006.1.iso / livecd.squashfs / usr / lib / mozilla-firefox / include / necko / nsNetUtil.h < prev    next >
C/C++ Source or Header  |  2006-05-08  |  35KB  |  997 lines

  1. /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
  2. /* vim:set ts=4 sw=4 sts=4 et cin: */
  3. /* ***** BEGIN LICENSE BLOCK *****
  4.  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
  5.  *
  6.  * The contents of this file are subject to the Mozilla Public License Version
  7.  * 1.1 (the "License"); you may not use this file except in compliance with
  8.  * the License. You may obtain a copy of the License at
  9.  * http://www.mozilla.org/MPL/
  10.  *
  11.  * Software distributed under the License is distributed on an "AS IS" basis,
  12.  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
  13.  * for the specific language governing rights and limitations under the
  14.  * License.
  15.  *
  16.  * The Original Code is mozilla.org code.
  17.  *
  18.  * The Initial Developer of the Original Code is
  19.  * Netscape Communications Corporation.
  20.  * Portions created by the Initial Developer are Copyright (C) 1998
  21.  * the Initial Developer. All Rights Reserved.
  22.  *
  23.  * Contributor(s):
  24.  *   Bradley Baetz <bbaetz@student.usyd.edu.au>
  25.  *   Malcolm Smith <malsmith@cs.rmit.edu.au>
  26.  *
  27.  * Alternatively, the contents of this file may be used under the terms of
  28.  * either the GNU General Public License Version 2 or later (the "GPL"), or
  29.  * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
  30.  * in which case the provisions of the GPL or the LGPL are applicable instead
  31.  * of those above. If you wish to allow use of your version of this file only
  32.  * under the terms of either the GPL or the LGPL, and not to allow others to
  33.  * use your version of this file under the terms of the MPL, indicate your
  34.  * decision by deleting the provisions above and replace them with the notice
  35.  * and other provisions required by the GPL or the LGPL. If you do not delete
  36.  * the provisions above, a recipient may use your version of this file under
  37.  * the terms of any one of the MPL, the GPL or the LGPL.
  38.  *
  39.  * ***** END LICENSE BLOCK ***** */
  40.  
  41. #ifndef nsNetUtil_h__
  42. #define nsNetUtil_h__
  43.  
  44. #include "nsNetError.h"
  45. #include "nsNetCID.h"
  46. #include "nsReadableUtils.h"
  47. #include "nsString.h"
  48. #include "nsMemory.h"
  49. #include "nsCOMPtr.h"
  50. #include "prio.h" // for read/write flags, permissions, etc.
  51.  
  52. #include "nsIURI.h"
  53. #include "nsIInputStream.h"
  54. #include "nsIOutputStream.h"
  55. #include "nsISafeOutputStream.h"
  56. #include "nsIStreamListener.h"
  57. #include "nsIRequestObserverProxy.h"
  58. #include "nsIStreamListenerProxy.h" // XXX for nsIAsyncStreamListener
  59. #include "nsISimpleStreamListener.h"
  60. #include "nsILoadGroup.h"
  61. #include "nsIInterfaceRequestor.h"
  62. #include "nsIInterfaceRequestorUtils.h"
  63. #include "nsIIOService.h"
  64. #include "nsIServiceManager.h"
  65. #include "nsIChannel.h"
  66. #include "nsIInputStreamChannel.h"
  67. #include "nsITransport.h"
  68. #include "nsIStreamTransportService.h"
  69. #include "nsIHttpChannel.h"
  70. #include "nsIDownloader.h"
  71. #include "nsIStreamLoader.h"
  72. #include "nsIUnicharStreamLoader.h"
  73. #include "nsIPipe.h"
  74. #include "nsIProtocolHandler.h"
  75. #include "nsIFileProtocolHandler.h"
  76. #include "nsIStringStream.h"
  77. #include "nsILocalFile.h"
  78. #include "nsIFileStreams.h"
  79. #include "nsIProtocolProxyService.h"
  80. #include "nsIProxyInfo.h"
  81. #include "nsIFileStreams.h"
  82. #include "nsIBufferedStreams.h"
  83. #include "nsIInputStreamPump.h"
  84. #include "nsIAsyncStreamCopier.h"
  85. #include "nsIPersistentProperties2.h"
  86. #include "nsISyncStreamListener.h"
  87. #include "nsInterfaceRequestorAgg.h"
  88. #include "nsInt64.h"
  89. #include "nsINetUtil.h"
  90.  
  91. // Helper, to simplify getting the I/O service.
  92. inline const nsGetServiceByCIDWithError
  93. do_GetIOService(nsresult* error = 0)
  94. {
  95.     static NS_DEFINE_CID(kIOServiceCID, NS_IOSERVICE_CID);
  96.     return nsGetServiceByCIDWithError(kIOServiceCID, error);
  97. }
  98.  
  99. // private little helper function... don't call this directly!
  100. inline nsresult
  101. net_EnsureIOService(nsIIOService **ios, nsCOMPtr<nsIIOService> &grip)
  102. {
  103.     nsresult rv = NS_OK;
  104.     if (!*ios) {
  105.         grip = do_GetIOService(&rv);
  106.         *ios = grip;
  107.     }
  108.     return rv;
  109. }
  110.  
  111. inline nsresult
  112. NS_NewURI(nsIURI **result, 
  113.           const nsACString &spec, 
  114.           const char *charset = nsnull,
  115.           nsIURI *baseURI = nsnull,
  116.           nsIIOService *ioService = nsnull)     // pass in nsIIOService to optimize callers
  117. {
  118.     nsresult rv;
  119.     nsCOMPtr<nsIIOService> grip;
  120.     rv = net_EnsureIOService(&ioService, grip);
  121.     if (ioService)
  122.         rv = ioService->NewURI(spec, charset, baseURI, result);
  123.     return rv; 
  124. }
  125.  
  126. inline nsresult
  127. NS_NewURI(nsIURI* *result, 
  128.           const nsAString& spec, 
  129.           const char *charset = nsnull,
  130.           nsIURI* baseURI = nsnull,
  131.           nsIIOService* ioService = nsnull)     // pass in nsIIOService to optimize callers
  132. {
  133.     return NS_NewURI(result, NS_ConvertUCS2toUTF8(spec), charset, baseURI, ioService);
  134. }
  135.  
  136. inline nsresult
  137. NS_NewURI(nsIURI* *result, 
  138.           const char *spec,
  139.           nsIURI* baseURI = nsnull,
  140.           nsIIOService* ioService = nsnull)     // pass in nsIIOService to optimize callers
  141. {
  142.     return NS_NewURI(result, nsDependentCString(spec), nsnull, baseURI, ioService);
  143. }
  144.  
  145. inline nsresult
  146. NS_NewFileURI(nsIURI* *result, 
  147.               nsIFile* spec, 
  148.               nsIIOService* ioService = nsnull)     // pass in nsIIOService to optimize callers
  149. {
  150.     nsresult rv;
  151.     nsCOMPtr<nsIIOService> grip;
  152.     rv = net_EnsureIOService(&ioService, grip);
  153.     if (ioService)
  154.         rv = ioService->NewFileURI(spec, result);
  155.     return rv;
  156. }
  157.  
  158. inline nsresult
  159. NS_NewChannel(nsIChannel           **result, 
  160.               nsIURI                *uri,
  161.               nsIIOService          *ioService = nsnull,    // pass in nsIIOService to optimize callers
  162.               nsILoadGroup          *loadGroup = nsnull,
  163.               nsIInterfaceRequestor *callbacks = nsnull,
  164.               PRUint32               loadFlags = nsIRequest::LOAD_NORMAL)
  165. {
  166.     nsresult rv;
  167.     nsCOMPtr<nsIIOService> grip;
  168.     rv = net_EnsureIOService(&ioService, grip);
  169.     if (ioService) {
  170.         nsIChannel *chan;
  171.         rv = ioService->NewChannelFromURI(uri, &chan);
  172.         if (NS_SUCCEEDED(rv)) {
  173.             if (loadGroup)
  174.                 rv |= chan->SetLoadGroup(loadGroup);
  175.             if (callbacks)
  176.                 rv |= chan->SetNotificationCallbacks(callbacks);
  177.             if (loadFlags != nsIRequest::LOAD_NORMAL)
  178.                 rv |= chan->SetLoadFlags(loadFlags);
  179.             if (NS_SUCCEEDED(rv))
  180.                 *result = chan;
  181.             else
  182.                 NS_RELEASE(chan);
  183.         }
  184.     }
  185.     return rv;
  186. }
  187.  
  188. // Use this function with CAUTION. It creates a stream that blocks when you
  189. // Read() from it and blocking the UI thread is a bad idea. If you don't want
  190. // to implement a full blown asynchronous consumer (via nsIStreamListener) look
  191. // at nsIStreamLoader instead.
  192. inline nsresult
  193. NS_OpenURI(nsIInputStream       **result,
  194.            nsIURI                *uri,
  195.            nsIIOService          *ioService = nsnull,     // pass in nsIIOService to optimize callers
  196.            nsILoadGroup          *loadGroup = nsnull,
  197.            nsIInterfaceRequestor *callbacks = nsnull,
  198.            PRUint32               loadFlags = nsIRequest::LOAD_NORMAL)
  199. {
  200.     nsresult rv;
  201.     nsCOMPtr<nsIChannel> channel;
  202.     rv = NS_NewChannel(getter_AddRefs(channel), uri, ioService,
  203.                        loadGroup, callbacks, loadFlags);
  204.     if (NS_SUCCEEDED(rv)) {
  205.         nsIInputStream *stream;
  206.         rv = channel->Open(&stream);
  207.         if (NS_SUCCEEDED(rv))
  208.             *result = stream;
  209.     }
  210.     return rv;
  211. }
  212.  
  213. inline nsresult
  214. NS_OpenURI(nsIStreamListener     *listener, 
  215.            nsISupports           *context, 
  216.            nsIURI                *uri,
  217.            nsIIOService          *ioService = nsnull,     // pass in nsIIOService to optimize callers
  218.            nsILoadGroup          *loadGroup = nsnull,
  219.            nsIInterfaceRequestor *callbacks = nsnull,
  220.            PRUint32               loadFlags = nsIRequest::LOAD_NORMAL)
  221. {
  222.     nsresult rv;
  223.     nsCOMPtr<nsIChannel> channel;
  224.     rv = NS_NewChannel(getter_AddRefs(channel), uri, ioService,
  225.                        loadGroup, callbacks, loadFlags);
  226.     if (NS_SUCCEEDED(rv))
  227.         rv = channel->AsyncOpen(listener, context);
  228.     return rv;
  229. }
  230.  
  231. inline nsresult
  232. NS_MakeAbsoluteURI(nsACString       &result,
  233.                    const nsACString &spec, 
  234.                    nsIURI           *baseURI, 
  235.                    nsIIOService     *unused = nsnull)
  236. {
  237.     nsresult rv;
  238.     if (!baseURI) {
  239.         NS_WARNING("It doesn't make sense to not supply a base URI");
  240.         result = spec;
  241.         rv = NS_OK;
  242.     }
  243.     else if (spec.IsEmpty())
  244.         rv = baseURI->GetSpec(result);
  245.     else
  246.         rv = baseURI->Resolve(spec, result);
  247.     return rv;
  248. }
  249.  
  250. inline nsresult
  251. NS_MakeAbsoluteURI(char        **result,
  252.                    const char   *spec, 
  253.                    nsIURI       *baseURI, 
  254.                    nsIIOService *unused = nsnull)
  255. {
  256.     nsresult rv;
  257.     nsCAutoString resultBuf;
  258.     rv = NS_MakeAbsoluteURI(resultBuf, nsDependentCString(spec), baseURI);
  259.     if (NS_SUCCEEDED(rv)) {
  260.         *result = ToNewCString(resultBuf);
  261.         if (!*result)
  262.             rv = NS_ERROR_OUT_OF_MEMORY;
  263.     }
  264.     return rv;
  265. }
  266.  
  267. inline nsresult
  268. NS_MakeAbsoluteURI(nsAString       &result,
  269.                    const nsAString &spec, 
  270.                    nsIURI          *baseURI,
  271.                    nsIIOService    *unused = nsnull)
  272. {
  273.     nsresult rv;
  274.     if (!baseURI) {
  275.         NS_WARNING("It doesn't make sense to not supply a base URI");
  276.         result = spec;
  277.         rv = NS_OK;
  278.     }
  279.     else {
  280.         nsCAutoString resultBuf;
  281.         if (spec.IsEmpty())
  282.             rv = baseURI->GetSpec(resultBuf);
  283.         else
  284.             rv = baseURI->Resolve(NS_ConvertUCS2toUTF8(spec), resultBuf);
  285.         if (NS_SUCCEEDED(rv))
  286.             CopyUTF8toUTF16(resultBuf, result);
  287.     }
  288.     return rv;
  289. }
  290.  
  291. inline nsresult
  292. NS_NewInputStreamChannel(nsIChannel      **result,
  293.                          nsIURI           *uri,
  294.                          nsIInputStream   *stream,
  295.                          const nsACString &contentType,
  296.                          const nsACString *contentCharset)
  297. {
  298.     nsresult rv;
  299.     static NS_DEFINE_CID(kInputStreamChannelCID, NS_INPUTSTREAMCHANNEL_CID);
  300.     nsCOMPtr<nsIInputStreamChannel> channel =
  301.         do_CreateInstance(kInputStreamChannelCID, &rv);
  302.     if (NS_SUCCEEDED(rv)) {
  303.         rv |= channel->SetURI(uri);
  304.         rv |= channel->SetContentStream(stream);
  305.         rv |= channel->SetContentType(contentType);
  306.         if (contentCharset && !contentCharset->IsEmpty()) {
  307.             rv |= channel->SetContentCharset(*contentCharset);
  308.         }
  309.         if (NS_SUCCEEDED(rv))
  310.             NS_ADDREF(*result = channel);
  311.     }
  312.     return rv;
  313. }
  314.  
  315. inline nsresult
  316. NS_NewInputStreamChannel(nsIChannel      **result,
  317.                          nsIURI           *uri,
  318.                          nsIInputStream   *stream,
  319.                          const nsACString &contentType    = EmptyCString())
  320. {
  321.     return NS_NewInputStreamChannel(result, uri, stream, contentType, nsnull);
  322. }
  323.  
  324. inline nsresult
  325. NS_NewInputStreamChannel(nsIChannel      **result,
  326.                          nsIURI           *uri,
  327.                          nsIInputStream   *stream,
  328.                          const nsACString &contentType,
  329.                          const nsACString &contentCharset)
  330. {
  331.     return NS_NewInputStreamChannel(result, uri, stream, contentType,
  332.                                     &contentCharset);
  333. }
  334.  
  335. inline nsresult
  336. NS_NewInputStreamPump(nsIInputStreamPump **result,
  337.                       nsIInputStream      *stream,
  338.                       PRInt64              streamPos = nsInt64(-1),
  339.                       PRInt64              streamLen = nsInt64(-1),
  340.                       PRUint32             segsize = 0,
  341.                       PRUint32             segcount = 0,
  342.                       PRBool               closeWhenDone = PR_FALSE)
  343. {
  344.     nsresult rv;
  345.     static NS_DEFINE_CID(kInputStreamPumpCID, NS_INPUTSTREAMPUMP_CID);
  346.     nsCOMPtr<nsIInputStreamPump> pump =
  347.         do_CreateInstance(kInputStreamPumpCID, &rv);
  348.     if (NS_SUCCEEDED(rv)) {
  349.         rv = pump->Init(stream, streamPos, streamLen,
  350.                         segsize, segcount, closeWhenDone);
  351.         if (NS_SUCCEEDED(rv))
  352.             NS_ADDREF(*result = pump);
  353.     }
  354.     return rv;
  355. }
  356.  
  357. // NOTE: you will need to specify whether or not your streams are buffered
  358. // (i.e., do they implement ReadSegments/WriteSegments).  the default
  359. // assumption of TRUE for both streams might not be right for you!
  360. inline nsresult
  361. NS_NewAsyncStreamCopier(nsIAsyncStreamCopier **result,
  362.                         nsIInputStream        *source,
  363.                         nsIOutputStream       *sink,
  364.                         nsIEventTarget        *target,
  365.                         PRBool                 sourceBuffered = PR_TRUE,
  366.                         PRBool                 sinkBuffered = PR_TRUE,
  367.                         PRUint32               chunkSize = 0)
  368. {
  369.     nsresult rv;
  370.     static NS_DEFINE_CID(kAsyncStreamCopierCID, NS_ASYNCSTREAMCOPIER_CID);
  371.     nsCOMPtr<nsIAsyncStreamCopier> copier =
  372.         do_CreateInstance(kAsyncStreamCopierCID, &rv);
  373.     if (NS_SUCCEEDED(rv)) {
  374.         rv = copier->Init(source, sink, target, sourceBuffered, sinkBuffered, chunkSize);
  375.         if (NS_SUCCEEDED(rv))
  376.             NS_ADDREF(*result = copier);
  377.     }
  378.     return rv;
  379. }
  380.  
  381. inline nsresult
  382. NS_NewLoadGroup(nsILoadGroup      **result,
  383.                 nsIRequestObserver *obs)
  384. {
  385.     nsresult rv;
  386.     static NS_DEFINE_CID(kLoadGroupCID, NS_LOADGROUP_CID);
  387.     nsCOMPtr<nsILoadGroup> group =
  388.         do_CreateInstance(kLoadGroupCID, &rv);
  389.     if (NS_SUCCEEDED(rv)) {
  390.         rv = group->SetGroupObserver(obs);
  391.         if (NS_SUCCEEDED(rv))
  392.             NS_ADDREF(*result = group);
  393.     }
  394.     return rv;
  395. }
  396.  
  397. inline nsresult
  398. NS_NewDownloader(nsIStreamListener   **result,
  399.                  nsIDownloadObserver  *observer,
  400.                  nsIFile              *downloadLocation = nsnull)
  401. {
  402.     nsresult rv;
  403.     static NS_DEFINE_CID(kDownloaderCID, NS_DOWNLOADER_CID);
  404.     nsCOMPtr<nsIDownloader> downloader =
  405.         do_CreateInstance(kDownloaderCID, &rv);
  406.     if (NS_SUCCEEDED(rv)) {
  407.         rv = downloader->Init(observer, downloadLocation);
  408.         if (NS_SUCCEEDED(rv))
  409.             NS_ADDREF(*result = downloader);
  410.     }
  411.     return rv;
  412. }
  413.  
  414. inline nsresult
  415. NS_NewStreamLoader(nsIStreamLoader        **aResult,
  416.                    nsIChannel              *aChannel,
  417.                    nsIStreamLoaderObserver *aObserver,
  418.                    nsISupports             *aContext)
  419. {
  420.     nsresult rv;
  421.     static NS_DEFINE_CID(kStreamLoaderCID, NS_STREAMLOADER_CID);
  422.     nsCOMPtr<nsIStreamLoader> loader =
  423.         do_CreateInstance(kStreamLoaderCID, &rv);
  424.     if (NS_SUCCEEDED(rv)) {
  425.         rv = loader->Init(aChannel, aObserver, aContext);
  426.         if (NS_SUCCEEDED(rv))
  427.             NS_ADDREF(*aResult = loader);
  428.     }
  429.     return rv;
  430. }
  431.  
  432. inline nsresult
  433. NS_NewStreamLoader(nsIStreamLoader        **result,
  434.                    nsIURI                  *uri,
  435.                    nsIStreamLoaderObserver *observer,
  436.                    nsISupports             *context   = nsnull,
  437.                    nsILoadGroup            *loadGroup = nsnull,
  438.                    nsIInterfaceRequestor   *callbacks = nsnull,
  439.                    PRUint32                 loadFlags = nsIRequest::LOAD_NORMAL,
  440.                    nsIURI                  *referrer  = nsnull)
  441. {
  442.     nsresult rv;
  443.     nsCOMPtr<nsIChannel> channel;
  444.     rv = NS_NewChannel(getter_AddRefs(channel),
  445.                        uri,
  446.                        nsnull,
  447.                        loadGroup,
  448.                        callbacks,
  449.                        loadFlags);
  450.     if (NS_SUCCEEDED(rv)) {
  451.         nsCOMPtr<nsIHttpChannel> httpChannel(do_QueryInterface(channel));
  452.         if (httpChannel)
  453.             httpChannel->SetReferrer(referrer);
  454.         rv = NS_NewStreamLoader(result, channel, observer, context);
  455.     }
  456.     return rv;
  457. }
  458.  
  459. inline nsresult
  460. NS_NewUnicharStreamLoader(nsIUnicharStreamLoader        **aResult,
  461.                           nsIChannel                     *aChannel,
  462.                           nsIUnicharStreamLoaderObserver *aObserver,
  463.                           nsISupports                    *aContext     = nsnull,
  464.                           PRUint32                        aSegmentSize = nsIUnicharStreamLoader::DEFAULT_SEGMENT_SIZE)
  465. {
  466.     nsresult rv;
  467.     static NS_DEFINE_CID(kUnicharStreamLoaderCID, NS_UNICHARSTREAMLOADER_CID);
  468.     nsCOMPtr<nsIUnicharStreamLoader> loader =
  469.         do_CreateInstance(kUnicharStreamLoaderCID, &rv);
  470.     if (NS_SUCCEEDED(rv)) {
  471.         rv = loader->Init(aChannel, aObserver, aContext, aSegmentSize);
  472.         if (NS_SUCCEEDED(rv))
  473.             NS_ADDREF(*aResult = loader);
  474.     }
  475.     return rv;
  476. }
  477.  
  478. inline nsresult
  479. NS_NewSyncStreamListener(nsIStreamListener **aResult,
  480.                          nsIInputStream    **aStream)
  481. {
  482.     nsresult rv;
  483.     static NS_DEFINE_CID(kSyncStreamListenerCID, NS_SYNCSTREAMLISTENER_CID);
  484.     nsCOMPtr<nsISyncStreamListener> listener =
  485.         do_CreateInstance(kSyncStreamListenerCID, &rv);
  486.     if (NS_SUCCEEDED(rv)) {
  487.         rv = listener->GetInputStream(aStream);
  488.         if (NS_SUCCEEDED(rv))
  489.             NS_ADDREF(*aResult = listener);
  490.     }
  491.     return rv;
  492. }
  493.  
  494. /**
  495.  * Implement the nsIChannel::Open(nsIInputStream**) method using the channel's
  496.  * AsyncOpen method.
  497.  *
  498.  * NOTE: Reading from the returned nsIInputStream may spin the current
  499.  * thread's event queue, which could result in any event being processed.
  500.  */
  501. inline nsresult
  502. NS_ImplementChannelOpen(nsIChannel      *aChannel,
  503.                         nsIInputStream **aResult)
  504. {
  505.     nsCOMPtr<nsIStreamListener> listener;
  506.     nsCOMPtr<nsIInputStream> stream;
  507.     nsresult rv = NS_NewSyncStreamListener(getter_AddRefs(listener),
  508.                                            getter_AddRefs(stream));
  509.     if (NS_SUCCEEDED(rv)) {
  510.         rv = aChannel->AsyncOpen(listener, nsnull);
  511.         if (NS_SUCCEEDED(rv)) {
  512.             PRUint32 n;
  513.             // block until the initial response is received or an error occurs.
  514.             rv = stream->Available(&n);
  515.             if (NS_SUCCEEDED(rv))
  516.                 NS_ADDREF(*aResult = stream);
  517.         }
  518.     }
  519.     return rv;
  520. }
  521.  
  522. inline nsresult
  523. NS_NewRequestObserverProxy(nsIRequestObserver **aResult,
  524.                            nsIRequestObserver  *aObserver,
  525.                            nsIEventQueue       *aEventQ = nsnull)
  526. {
  527.     nsresult rv;
  528.     static NS_DEFINE_CID(kRequestObserverProxyCID, NS_REQUESTOBSERVERPROXY_CID);
  529.     nsCOMPtr<nsIRequestObserverProxy> proxy =
  530.         do_CreateInstance(kRequestObserverProxyCID, &rv);
  531.     if (NS_SUCCEEDED(rv)) {
  532.         rv = proxy->Init(aObserver, aEventQ);
  533.         if (NS_SUCCEEDED(rv))
  534.             NS_ADDREF(*aResult = proxy);
  535.     }
  536.     return rv;
  537. }
  538.  
  539. inline nsresult
  540. NS_NewSimpleStreamListener(nsIStreamListener **aResult,
  541.                            nsIOutputStream    *aSink,
  542.                            nsIRequestObserver *aObserver = nsnull)
  543. {
  544.     nsresult rv;
  545.     static NS_DEFINE_CID(kSimpleStreamListenerCID, NS_SIMPLESTREAMLISTENER_CID);
  546.     nsCOMPtr<nsISimpleStreamListener> listener = 
  547.         do_CreateInstance(kSimpleStreamListenerCID, &rv);
  548.     if (NS_SUCCEEDED(rv)) {
  549.         rv = listener->Init(aSink, aObserver);
  550.         if (NS_SUCCEEDED(rv))
  551.             NS_ADDREF(*aResult = listener);
  552.     }
  553.     return rv;
  554. }
  555.  
  556. inline nsresult
  557. NS_NewAsyncStreamListener(nsIStreamListener **result,
  558.                           nsIStreamListener  *receiver,
  559.                           nsIEventQueue      *eventQueue)
  560. {
  561.     nsresult rv;
  562.     static NS_DEFINE_CID(kAsyncStreamListenerCID, NS_ASYNCSTREAMLISTENER_CID);
  563.     nsCOMPtr<nsIAsyncStreamListener> lsnr =
  564.         do_CreateInstance(kAsyncStreamListenerCID, &rv);
  565.     if (NS_SUCCEEDED(rv)) {
  566.         rv = lsnr->Init(receiver, eventQueue);
  567.         if (NS_SUCCEEDED(rv))
  568.             NS_ADDREF(*result = lsnr);
  569.     }
  570.     return rv;
  571. }
  572.  
  573. inline nsresult
  574. NS_CheckPortSafety(PRInt32       port,
  575.                    const char   *scheme,
  576.                    nsIIOService *ioService = nsnull)
  577. {
  578.     nsresult rv;
  579.     nsCOMPtr<nsIIOService> grip;
  580.     rv = net_EnsureIOService(&ioService, grip);
  581.     if (ioService) {
  582.         PRBool allow;
  583.         rv = ioService->AllowPort(port, scheme, &allow);
  584.         if (NS_SUCCEEDED(rv) && !allow)
  585.             rv = NS_ERROR_PORT_ACCESS_NOT_ALLOWED;
  586.     }
  587.     return rv;
  588. }
  589.  
  590. inline nsresult
  591. NS_NewProxyInfo(const nsACString &type,
  592.                 const nsACString &host,
  593.                 PRInt32           port,
  594.                 PRUint32          flags,
  595.                 nsIProxyInfo    **result)
  596. {
  597.     nsresult rv;
  598.     static NS_DEFINE_CID(kPPSServiceCID, NS_PROTOCOLPROXYSERVICE_CID);
  599.     nsCOMPtr<nsIProtocolProxyService> pps = do_GetService(kPPSServiceCID, &rv);
  600.     if (NS_SUCCEEDED(rv))
  601.         rv = pps->NewProxyInfo(type, host, port, flags, PR_UINT32_MAX, nsnull,
  602.                                result);
  603.     return rv; 
  604. }
  605.  
  606. inline nsresult
  607. NS_GetFileProtocolHandler(nsIFileProtocolHandler **result,
  608.                           nsIIOService            *ioService = nsnull)
  609. {
  610.     nsresult rv;
  611.     nsCOMPtr<nsIIOService> grip;
  612.     rv = net_EnsureIOService(&ioService, grip);
  613.     if (ioService) {
  614.         nsCOMPtr<nsIProtocolHandler> handler;
  615.         rv = ioService->GetProtocolHandler("file", getter_AddRefs(handler));
  616.         if (NS_SUCCEEDED(rv))
  617.             rv = CallQueryInterface(handler, result);
  618.     }
  619.     return rv;
  620. }
  621.  
  622. inline nsresult
  623. NS_GetFileFromURLSpec(const nsACString  &inURL,
  624.                       nsIFile          **result,
  625.                       nsIIOService      *ioService = nsnull)
  626. {
  627.     nsresult rv;
  628.     nsCOMPtr<nsIFileProtocolHandler> fileHandler;
  629.     rv = NS_GetFileProtocolHandler(getter_AddRefs(fileHandler), ioService);
  630.     if (NS_SUCCEEDED(rv))
  631.         rv = fileHandler->GetFileFromURLSpec(inURL, result);
  632.     return rv;
  633. }
  634.  
  635. inline nsresult
  636. NS_GetURLSpecFromFile(nsIFile      *aFile,
  637.                       nsACString   &aUrl,
  638.                       nsIIOService *ioService = nsnull)
  639. {
  640.     nsresult rv;
  641.     nsCOMPtr<nsIFileProtocolHandler> fileHandler;
  642.     rv = NS_GetFileProtocolHandler(getter_AddRefs(fileHandler), ioService);
  643.     if (NS_SUCCEEDED(rv))
  644.         rv = fileHandler->GetURLSpecFromFile(aFile, aUrl);
  645.     return rv;
  646. }
  647.  
  648. inline nsresult
  649. NS_ExamineForProxy(const char    *scheme,
  650.                    const char    *host,
  651.                    PRInt32        port, 
  652.                    nsIProxyInfo **proxyInfo)
  653. {
  654.     nsresult rv;
  655.     static NS_DEFINE_CID(kPPSServiceCID, NS_PROTOCOLPROXYSERVICE_CID);
  656.     nsCOMPtr<nsIProtocolProxyService> pps = do_GetService(kPPSServiceCID, &rv);
  657.     if (NS_SUCCEEDED(rv)) {
  658.         nsCAutoString spec(scheme);
  659.         spec.Append("://");
  660.         spec.Append(host);
  661.         spec.Append(':');
  662.         spec.AppendInt(port);
  663.         // XXXXX - Under no circumstances whatsoever should any code which
  664.         // wants a uri do this. I do this here because I do not, in fact,
  665.         // actually want a uri (the dummy uris created here may not be 
  666.         // syntactically valid for the specific protocol), and all we need
  667.         // is something which has a valid scheme, hostname, and a string
  668.         // to pass to PAC if needed - bbaetz
  669.         static NS_DEFINE_CID(kStandardURLCID, NS_STANDARDURL_CID);    
  670.         nsCOMPtr<nsIURI> uri = do_CreateInstance(kStandardURLCID, &rv);
  671.         if (NS_SUCCEEDED(rv)) {
  672.             rv = uri->SetSpec(spec);
  673.             if (NS_SUCCEEDED(rv))
  674.                 rv = pps->Resolve(uri, 0, proxyInfo);
  675.         }
  676.     }
  677.     return rv;
  678. }
  679.  
  680. inline nsresult
  681. NS_ParseContentType(const nsACString &rawContentType,
  682.                     nsCString        &contentType,
  683.                     nsCString        &contentCharset)
  684. {
  685.     // contentCharset is left untouched if not present in rawContentType
  686.     nsresult rv;
  687.     nsCOMPtr<nsINetUtil> util = do_GetIOService(&rv);
  688.     NS_ENSURE_SUCCESS(rv, rv);
  689.     nsCString charset;
  690.     PRBool hadCharset;
  691.     rv = util->ParseContentType(rawContentType, charset, &hadCharset,
  692.                                 contentType);
  693.     if (NS_SUCCEEDED(rv) && hadCharset)
  694.         contentCharset = charset;
  695.     return rv;
  696. }
  697.  
  698. inline nsresult
  699. NS_NewLocalFileInputStream(nsIInputStream **aResult,
  700.                            nsIFile         *aFile,
  701.                            PRInt32          aIOFlags       = -1,
  702.                            PRInt32          aPerm          = -1,
  703.                            PRInt32          aBehaviorFlags = 0)
  704. {
  705.     nsresult rv;
  706.     static NS_DEFINE_CID(kLocalFileInputStreamCID, NS_LOCALFILEINPUTSTREAM_CID);
  707.     nsCOMPtr<nsIFileInputStream> in =
  708.         do_CreateInstance(kLocalFileInputStreamCID, &rv);
  709.     if (NS_SUCCEEDED(rv)) {
  710.         rv = in->Init(aFile, aIOFlags, aPerm, aBehaviorFlags);
  711.         if (NS_SUCCEEDED(rv))
  712.             NS_ADDREF(*aResult = in);
  713.     }
  714.     return rv;
  715. }
  716.  
  717. inline nsresult
  718. NS_NewLocalFileOutputStream(nsIOutputStream **aResult,
  719.                             nsIFile          *aFile,
  720.                             PRInt32           aIOFlags       = -1,
  721.                             PRInt32           aPerm          = -1,
  722.                             PRInt32           aBehaviorFlags = 0)
  723. {
  724.     nsresult rv;
  725.     static NS_DEFINE_CID(kLocalFileOutputStreamCID, NS_LOCALFILEOUTPUTSTREAM_CID);
  726.     nsCOMPtr<nsIFileOutputStream> out =
  727.         do_CreateInstance(kLocalFileOutputStreamCID, &rv);
  728.     if (NS_SUCCEEDED(rv)) {
  729.         rv = out->Init(aFile, aIOFlags, aPerm, aBehaviorFlags);
  730.         if (NS_SUCCEEDED(rv))
  731.             NS_ADDREF(*aResult = out);
  732.     }
  733.     return rv;
  734. }
  735.  
  736. // returns a file output stream which can be QI'ed to nsISafeOutputStream.
  737. inline nsresult
  738. NS_NewSafeLocalFileOutputStream(nsIOutputStream **aResult,
  739.                                 nsIFile          *aFile,
  740.                                 PRInt32           aIOFlags       = -1,
  741.                                 PRInt32           aPerm          = -1,
  742.                                 PRInt32           aBehaviorFlags = 0)
  743. {
  744.     nsresult rv;
  745.     static NS_DEFINE_CID(kSafeLocalFileOutputStreamCID, NS_SAFELOCALFILEOUTPUTSTREAM_CID);
  746.     nsCOMPtr<nsIFileOutputStream> out =
  747.         do_CreateInstance(kSafeLocalFileOutputStreamCID, &rv);
  748.     if (NS_SUCCEEDED(rv)) {
  749.         rv = out->Init(aFile, aIOFlags, aPerm, aBehaviorFlags);
  750.         if (NS_SUCCEEDED(rv))
  751.             NS_ADDREF(*aResult = out);
  752.     }
  753.     return rv;
  754. }
  755.  
  756. // returns the input end of a pipe.  the output end of the pipe
  757. // is attached to the original stream.  data from the original
  758. // stream is read into the pipe on a background thread.
  759. inline nsresult
  760. NS_BackgroundInputStream(nsIInputStream **aResult,
  761.                          nsIInputStream  *aStream,
  762.                          PRUint32         aSegmentSize  = 0,
  763.                          PRUint32         aSegmentCount = 0)
  764. {
  765.     nsresult rv;
  766.     nsCOMPtr<nsIStreamTransportService> sts =
  767.         do_GetService(NS_STREAMTRANSPORTSERVICE_CONTRACTID, &rv);
  768.     if (NS_SUCCEEDED(rv)) {
  769.         nsCOMPtr<nsITransport> inTransport;
  770.         rv = sts->CreateInputTransport(aStream, nsInt64(-1), nsInt64(-1), PR_TRUE,
  771.                                        getter_AddRefs(inTransport));
  772.         if (NS_SUCCEEDED(rv))
  773.             rv = inTransport->OpenInputStream(nsITransport::OPEN_BLOCKING,
  774.                                               aSegmentSize, aSegmentCount,
  775.                                               aResult);
  776.     }
  777.     return rv;
  778. }
  779.  
  780. // returns the output end of a pipe.  the input end of the pipe
  781. // is attached to the original stream.  data written to the pipe
  782. // is copied to the original stream on a background thread.
  783. inline nsresult
  784. NS_BackgroundOutputStream(nsIOutputStream **aResult,
  785.                           nsIOutputStream  *aStream,
  786.                           PRUint32          aSegmentSize  = 0,
  787.                           PRUint32          aSegmentCount = 0)
  788. {
  789.     nsresult rv;
  790.     nsCOMPtr<nsIStreamTransportService> sts =
  791.         do_GetService(NS_STREAMTRANSPORTSERVICE_CONTRACTID, &rv);
  792.     if (NS_SUCCEEDED(rv)) {
  793.         nsCOMPtr<nsITransport> inTransport;
  794.         rv = sts->CreateOutputTransport(aStream, nsInt64(-1), nsInt64(-1), PR_TRUE,
  795.                                         getter_AddRefs(inTransport));
  796.         if (NS_SUCCEEDED(rv))
  797.             rv = inTransport->OpenOutputStream(nsITransport::OPEN_BLOCKING,
  798.                                                aSegmentSize, aSegmentCount,
  799.                                                aResult);
  800.     }
  801.     return rv;
  802. }
  803.  
  804. inline nsresult
  805. NS_NewBufferedInputStream(nsIInputStream **aResult,
  806.                           nsIInputStream *aStr,
  807.                           PRUint32        aBufferSize)
  808. {
  809.     nsresult rv;
  810.     static NS_DEFINE_CID(kBufferedInputStreamCID, NS_BUFFEREDINPUTSTREAM_CID);
  811.     nsCOMPtr<nsIBufferedInputStream> in =
  812.         do_CreateInstance(kBufferedInputStreamCID, &rv);
  813.     if (NS_SUCCEEDED(rv)) {
  814.         rv = in->Init(aStr, aBufferSize);
  815.         if (NS_SUCCEEDED(rv))
  816.             NS_ADDREF(*aResult = in);
  817.     }
  818.     return rv;
  819. }
  820.  
  821. // note: the resulting stream can be QI'ed to nsISafeOutputStream iff the
  822. // provided stream supports it.
  823. inline nsresult
  824. NS_NewBufferedOutputStream(nsIOutputStream **aResult,
  825.                            nsIOutputStream  *aStr,
  826.                            PRUint32          aBufferSize)
  827. {
  828.     nsresult rv;
  829.     static NS_DEFINE_CID(kBufferedOutputStreamCID, NS_BUFFEREDOUTPUTSTREAM_CID);
  830.     nsCOMPtr<nsIBufferedOutputStream> out =
  831.         do_CreateInstance(kBufferedOutputStreamCID, &rv);
  832.     if (NS_SUCCEEDED(rv)) {
  833.         rv = out->Init(aStr, aBufferSize);
  834.         if (NS_SUCCEEDED(rv))
  835.             NS_ADDREF(*aResult = out);
  836.     }
  837.     return rv;
  838. }
  839.  
  840. // returns an input stream compatible with nsIUploadChannel::SetUploadStream()
  841. inline nsresult
  842. NS_NewPostDataStream(nsIInputStream  **result,
  843.                      PRBool            isFile,
  844.                      const nsACString &data,
  845.                      PRUint32          encodeFlags,
  846.                      nsIIOService     *unused = nsnull)
  847. {
  848.     if (isFile) {
  849.         nsresult rv;
  850.         nsCOMPtr<nsILocalFile> file;
  851.         nsCOMPtr<nsIInputStream> fileStream;
  852.  
  853.         rv = NS_NewNativeLocalFile(data, PR_FALSE, getter_AddRefs(file));
  854.         if (NS_SUCCEEDED(rv)) {
  855.             rv = NS_NewLocalFileInputStream(getter_AddRefs(fileStream), file);
  856.             if (NS_SUCCEEDED(rv)) {
  857.                 // wrap the file stream with a buffered input stream
  858.                 rv = NS_NewBufferedInputStream(result, fileStream, 8192);
  859.             }
  860.         }
  861.         return rv;
  862.     }
  863.  
  864.     // otherwise, create a string stream for the data (copies)
  865.     return NS_NewCStringInputStream(result, data);
  866. }
  867.  
  868. inline nsresult
  869. NS_LoadPersistentPropertiesFromURI(nsIPersistentProperties **result,
  870.                                    nsIURI                  *uri,
  871.                                    nsIIOService            *ioService = nsnull)
  872. {
  873.     nsCOMPtr<nsIInputStream> in;
  874.     nsresult rv = NS_OpenURI(getter_AddRefs(in), uri, ioService);
  875.     if (NS_SUCCEEDED(rv)) {
  876.         nsCOMPtr<nsIPersistentProperties> properties = 
  877.             do_CreateInstance(NS_PERSISTENTPROPERTIES_CONTRACTID, &rv);
  878.         if (NS_SUCCEEDED(rv)) {
  879.             rv = properties->Load(in);
  880.             if (NS_SUCCEEDED(rv))
  881.                 NS_ADDREF(*result = properties);
  882.         }
  883.     }
  884.     return rv;
  885. }
  886.  
  887. inline nsresult
  888. NS_LoadPersistentPropertiesFromURISpec(nsIPersistentProperties **result,
  889.                                        const nsACString        &spec,
  890.                                        const char              *charset = nsnull,
  891.                                        nsIURI                  *baseURI = nsnull,
  892.                                        nsIIOService            *ioService = nsnull)     
  893. {
  894.     nsCOMPtr<nsIURI> uri;
  895.     nsresult rv = 
  896.         NS_NewURI(getter_AddRefs(uri), spec, charset, baseURI, ioService);
  897.  
  898.     if (NS_SUCCEEDED(rv))
  899.         rv = NS_LoadPersistentPropertiesFromURI(result, uri, ioService);
  900.  
  901.     return rv;
  902. }
  903.  
  904. /**
  905.  * NS_QueryNotificationCallbacks implements the canonical algorithm for
  906.  * querying interfaces from a channel's notification callbacks.  It first
  907.  * searches the channel's notificationCallbacks attribute, and if the interface
  908.  * is not found there, then it inspects the notificationCallbacks attribute of
  909.  * the channel's loadGroup.
  910.  */
  911. inline void
  912. NS_QueryNotificationCallbacks(nsIChannel   *aChannel,
  913.                               const nsIID  &aIID,
  914.                               void        **aResult)
  915. {
  916.     NS_PRECONDITION(aChannel, "null channel");
  917.     *aResult = nsnull;
  918.  
  919.     nsCOMPtr<nsIInterfaceRequestor> cbs;
  920.     aChannel->GetNotificationCallbacks(getter_AddRefs(cbs));
  921.     if (cbs)
  922.         cbs->GetInterface(aIID, aResult);
  923.     if (!*aResult) {
  924.         // try load group's notification callbacks...
  925.         nsCOMPtr<nsILoadGroup> loadGroup;
  926.         aChannel->GetLoadGroup(getter_AddRefs(loadGroup));
  927.         if (loadGroup) {
  928.             loadGroup->GetNotificationCallbacks(getter_AddRefs(cbs));
  929.             if (cbs)
  930.                 cbs->GetInterface(aIID, aResult);
  931.         }
  932.     }
  933. }
  934.  
  935. /* template helper */
  936. template <class T> inline void
  937. NS_QueryNotificationCallbacks(nsIChannel  *aChannel,
  938.                               nsCOMPtr<T> &aResult)
  939. {
  940.     NS_QueryNotificationCallbacks(aChannel, NS_GET_IID(T),
  941.                                   getter_AddRefs(aResult));
  942. }
  943.  
  944. /**
  945.  * Alternate form of NS_QueryNotificationCallbacks designed for use by
  946.  * nsIChannel implementations.
  947.  */
  948. inline void
  949. NS_QueryNotificationCallbacks(nsIInterfaceRequestor  *aCallbacks,
  950.                               nsILoadGroup           *aLoadGroup,
  951.                               const nsIID            &aIID,
  952.                               void                  **aResult)
  953. {
  954.     *aResult = nsnull;
  955.  
  956.     if (aCallbacks)
  957.         aCallbacks->GetInterface(aIID, aResult);
  958.     if (!*aResult) {
  959.         // try load group's notification callbacks...
  960.         if (aLoadGroup) {
  961.             nsCOMPtr<nsIInterfaceRequestor> cbs;
  962.             aLoadGroup->GetNotificationCallbacks(getter_AddRefs(cbs));
  963.             if (cbs)
  964.                 cbs->GetInterface(aIID, aResult);
  965.         }
  966.     }
  967. }
  968.  
  969. /* template helper */
  970. template <class T> inline void
  971. NS_QueryNotificationCallbacks(nsIInterfaceRequestor *aCallbacks,
  972.                               nsILoadGroup          *aLoadGroup,
  973.                               nsCOMPtr<T>           &aResult)
  974. {
  975.     NS_QueryNotificationCallbacks(aCallbacks, aLoadGroup,
  976.                                   NS_GET_IID(T),
  977.                                   getter_AddRefs(aResult));
  978. }
  979.  
  980. /**
  981.  * This function returns a nsIInterfaceRequestor instance that returns the
  982.  * same result as NS_QueryNotificationCallbacks when queried.  It is useful
  983.  * as the value for nsISocketTransport::securityCallbacks.
  984.  */
  985. inline nsresult
  986. NS_NewNotificationCallbacksAggregation(nsIInterfaceRequestor  *aCallbacks,
  987.                                        nsILoadGroup           *aLoadGroup,
  988.                                        nsIInterfaceRequestor **aResult)
  989. {
  990.     nsCOMPtr<nsIInterfaceRequestor> cbs;
  991.     if (aLoadGroup)
  992.         aLoadGroup->GetNotificationCallbacks(getter_AddRefs(cbs));
  993.     return NS_NewInterfaceRequestorAggregation(aCallbacks, cbs, aResult);
  994. }
  995.  
  996. #endif // !nsNetUtil_h__
  997.